package cn.mybatishelper.builder;

import cn.mybatishelper.baseEnum.DataBaseTypeEnum;
import cn.mybatishelper.common.BaseInfoConstants;
import cn.mybatishelper.common.JdbcUtil;
import cn.mybatishelper.entity.CreateFile;
import cn.mybatishelper.entity.database.DatabaseEntity;
import cn.mybatishelper.entity.java.MapperEntity;
import cn.mybatishelper.entity.java.PersistenceEntity;
import cn.mybatishelper.entity.vo.TableToMybatisVo;
import cn.mybatishelper.entity.xml.DefaultXMLEntity;
import cn.mybatishelper.handler.DefaultHandler;
import cn.mybatishelper.handler.Handler;
import cn.mybatishelper.parser.jdbcParser.AbstractJdbcParser;
import cn.mybatishelper.parser.jdbcParser.JdbcParser;
import cn.mybatishelper.parser.jdbcParser.OracleJdbcParser;
import cn.mybatishelper.parser.jdbcParser.PostgresqlJdbcParser;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 默认文件处理器装配类
 *
 * @author GameKing
 */
public class DefaultHandlerBuilder implements Builder {
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHandlerBuilder.class);
    /**
     * source folder 路径，生成文件使用
     */
    private String rootFilePath;
    /**
     * 数据库解析器
     */
    private AbstractJdbcParser jdbcParser;
    /**
     * mapper需要继承的父类的完整路径
     */
    private String extendsClassUrl;
    /**
     * 数据库表和需要生成的业务类信息的集合列表
     */
    private List<TableToMybatisVo> voList;

    public DefaultHandlerBuilder() {
    }

    public DefaultHandlerBuilder(String extendsClassUrl, AbstractJdbcParser jdbcParser, String rootFilePath, List<TableToMybatisVo> voList) {
        this.extendsClassUrl = extendsClassUrl;
        this.jdbcParser = jdbcParser;
        this.rootFilePath = rootFilePath;
        this.voList = voList;
    }

    @Override
    public void buildJdbcParser() {
        if (DataBaseTypeEnum.ORACLE.getDataBaseType().equals(BaseInfoConstants.dataBaseType)) {
            this.jdbcParser = new OracleJdbcParser();
        } else {
            this.jdbcParser = new PostgresqlJdbcParser();
        }
        this.jdbcParser.setAddressUrl(BaseInfoConstants.dataBaseAddr);
        this.jdbcParser.setUserName(BaseInfoConstants.dataBaseAccount);
        this.jdbcParser.setPassword(BaseInfoConstants.dataBasePassword);
        this.jdbcParser.setSchemaName(BaseInfoConstants.dataBaseSchema);
    }

    @Override
    public void buildTableToMybatisVos() {
        this.voList = JdbcUtil.createTableToMybatisFromBaseConstants();
    }

    @Override
    public void buildRootFilePath() {
        this.rootFilePath = BaseInfoConstants.rootDir;
    }

    @Override
    public void buildMapperExtendUrl() {
        this.extendsClassUrl = BaseInfoConstants.mapperExtendJavaUrl;
    }

    @Override
    public void execute() {
        if (!validate()) {
            LOGGER.error("有效性验证失败，不予执行...");
            return;
        }
        try {
            List<DatabaseEntity> entities = jdbcParser.getJdbcEntitys(this.voList);
            if (CollectionUtils.isNotEmpty(entities)) {
                List<CreateFile> createFiles = new ArrayList<CreateFile>();
                DefaultXMLEntity defaultXMLEntity = new DefaultXMLEntity(rootFilePath);
                createFiles.add(defaultXMLEntity);
                createFiles.add(new PersistenceEntity(rootFilePath));
                createFiles.add(new MapperEntity(rootFilePath, extendsClassUrl, defaultXMLEntity));

                Handler handler = new DefaultHandler(entities, createFiles);
                handler.execute();
            } else {
                LOGGER.info("根据相关参数无法获取任何数据库实体,程序不予执行...");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean validate() {
        if (!jdbcParser.validateParser()) {
            LOGGER.error("验证有效性时：数据库解析器不合法...");
            return false;
        }
        if (StringUtils.isEmpty(rootFilePath)) {
            LOGGER.error("验证有效性时：classpath为空...");
            return false;
        }
        if (CollectionUtils.isEmpty(voList)) {
            LOGGER.error("验证有效性时：voList为空...");
            return false;
        }
        return true;
    }


    /**
     * ******************************get/set********************************************************
     */

    public String getRootFilePath() {
        return rootFilePath;
    }

    public void setRootFilePath(String rootFilePath) {
        this.rootFilePath = rootFilePath;
    }

    public String getExtendsClassUrl() {
        return extendsClassUrl;
    }

    public void setExtendsClassUrl(String extendsClassUrl) {
        this.extendsClassUrl = extendsClassUrl;
    }

    public JdbcParser getJdbcParser() {
        return jdbcParser;
    }

    public void setJdbcParser(AbstractJdbcParser jdbcParser) {
        this.jdbcParser = jdbcParser;
    }

    public List<TableToMybatisVo> getVoList() {
        return voList;
    }

    public void setVoList(List<TableToMybatisVo> voList) {
        this.voList = voList;
    }
}
